#include <stdlib.h>

#include "userConfig.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "ff.h"


/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1           /* 任务优先级 */
#define START_STK_SIZE          256         /* 任务堆栈大小 */
TaskHandle_t StartTask_Handler;             /* 任务句柄 */

/* LWIP_DEMO 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define LWIP_DMEO_TASK_PRIO     11          /* 任务优先级 */
#define LWIP_DMEO_STK_SIZE      1024        /* 任务堆栈大小 */
TaskHandle_t LWIP_Task_Handler;             /* 任务句柄 */

void sd_test_fatfs(void)
{
    FRESULT ret;
    FATFS *fs_obj;
    FIL *fil_obj;
    uint8_t rd_buf[255] = {0};
    uint16_t fsize = 0;
    uint16_t rd_conut, wd_conut;

    fs_obj = (FATFS *)pvPortMalloc(sizeof(FATFS));
    fil_obj = (FIL *)pvPortMalloc(sizeof(FIL));

    /* 1 挂载SD卡设备 */
    ret = f_mount(fs_obj, "0:", 1);
    if (ret)
    {
        usart_transmit("mount fail %d \r\n", ret);
    }
    else
    {
        usart_transmit("mount OK\r\n");
    }

    /* 2 打开文件(需要注意要关闭文件f_close) */
    ret = f_open(fil_obj, "0:text.txt", FA_READ | FA_WRITE | FA_OPEN_ALWAYS);
    if (ret)
    {
        usart_transmit("open fail %d \r\n", ret);
    }
    else
    {
        usart_transmit("open OK\r\n");
    }

    /* 3 读取数据 */
    fsize = f_size(fil_obj);
    f_read(fil_obj, rd_buf, fsize, (UINT *)&rd_conut);
    if (rd_conut != 0)
    {
        usart_transmit("rd_conut:%d rd_buf:%s \r\n",rd_conut, rd_buf);
    }

    /* 4 数据写入 */            /* 注意：读写指针 */
    f_write(fil_obj, "333", 3, (UINT *)&wd_conut);

    f_lseek(fil_obj, 0);
    fsize = f_size(fil_obj);
    f_read(fil_obj, rd_buf, fsize, (UINT *)&rd_conut);
    if (rd_conut != 0)
    {
        usart_transmit("rd_conut:%d rd_buf:%s \r\n",rd_conut, rd_buf);
    }

    /* 5 关闭文件 */
    f_close(fil_obj);
}

void sd_test_mkfs()
{
    BYTE work[1024];
    f_mkfs("0:", NULL, work, sizeof(work));
}

/**
 * @brief       lwIP运行例程
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void fatfs_demo_task(void *pvParameters)
{
    // sd_test_fatfs();
    sd_test_mkfs();
    /**
     * FreeRTOS中任务执行 函数模型是一个while(1)的循环体，不循序跳出循环，如果
     * 一定要跳出循环体的话，跳出循环后执行删除任务，不然，会触发assert();
     */
    vTaskDelete(LWIP_Task_Handler);
}

/**
 * @brief       start_task
 * @param       pvParameters : 传入参数
 * @retval      无
 */
static void start_task_demo(void *pvParameters)
{
    pvParameters = pvParameters;

    /* 进入临界区 */
    taskENTER_CRITICAL();

    /* 创建lwIP任务 */
    xTaskCreate((TaskFunction_t )fatfs_demo_task,
                (const char*    )"fatfs_demo_task",
                (uint16_t       )LWIP_DMEO_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )LWIP_DMEO_TASK_PRIO,
                (TaskHandle_t*  )&LWIP_Task_Handler);

    /* 删除开始任务 */
    vTaskDelete(StartTask_Handler);
    /* 退出临界区 */
    taskEXIT_CRITICAL();
}

/**
 * @breif       fatfs_demo
 * @param       无
 * @retval      无
 */
void fatfs_demo(void)
{
    /* start_task */
    xTaskCreate((TaskFunction_t )start_task_demo,       /* 任务函数 */
                (const char *   )"start_task",          /* 任务名称 */
                (uint16_t       )START_STK_SIZE,        /* 任务堆栈 */
                (void *         )NULL,                  /* 传递给任务函数的参数 */
                (UBaseType_t    )START_TASK_PRIO,       /* 任务的优先级 */
                (TaskHandle_t * )&StartTask_Handler);   /* 任务句柄 */

    /* 开启任务调度 */
    vTaskStartScheduler();
}
